﻿using ReflectionStudio.Core.Events;
using System;
using System.Data;
using System.Linq;
using WPFExcelReport.Helpers;
using System.Collections;
using System.Collections.Generic;
using WPFExcelReport;
namespace INTEX.SCHEDULER
{

    public partial class ITXSSPA
    {

        private JMRULES _JMRULES;
        public JMRULES JMRULES
        {
            get
            {
                if (_JMRULES == null)
                {
                    _JMRULES = new JMRULES();
                    _JMRULES.TBSTDM = TBSTDM;
                    _JMRULES.srcSRULES = srcSRULES;

                }
                return _JMRULES;
            }
        }
        public virtual void ResetJob()
        {

            var qjob = from DataRow row in TVKPJOBS.AsEnumerable()
                       orderby row.Field<string>("ABFSTATUS") descending
                       orderby row.Field<string>("SPCONFIRM") descending
                       select row;
            foreach (DataRow dwJob in qjob)
            {

                if (dwJob["ABFSTATUS"].ToString() == "R")//已经开始生产的任务
                {
                    dwJob["JP11"] = 0;
                    continue;
                }
                if (dwJob["JOBTYPE"].ToString().Trim() == "C")//已经确认的任务
                {
                    dwJob["JP11"] = 0;
                    continue;
                }
                if (dwJob["JOBTYPE"].ToString().Trim() == "X")//日历任务
                {
                    dwJob["JP11"] = 0;
                    continue;
                }
                GetJobReady(dwJob);
                dwJob["ABFBLFDNR"] = "0000";
                dwJob["BLOCKEDID"] = "0";
                dwJob["MATBLOCKID"] = "0";
                dwJob["JOBTYPE"] = " ";
            }
            AdvanceFirstMKTP();
            filter = "ABFBLFDNR<>'0000' AND JOBTYPE<>'X'";
            sort = "JWDRATIO DESC,WDRATIO DESC,JDRATIO DESC,JWDNUM DESC,WDNUM DESC,JDNUM DESC,JWNUM ASC,WNUM ASC,JNUM ASC,RVKKLINES ASC,SVKKLINES ASC,VKKLINES ASC ,RGB ASC,ABFSOLLDAT ASC ,VKPLIEFTERM ASC,VKPNEUDAT ASC";
            rows = TVKPJOBS.Select(filter, sort);
            foreach (DataRow dwJob in rows)
            {
                UpdateAB(dwJob);
                UpdateArticle(dwJob);
                UpdateVKK(dwJob);
            }
        }
        public virtual void AdvanceFirstMKTP()
        {
            filter = "JOBTYPE<>'X'";
        }
        public void GetJobReady(DataRow dwJob)
        {
            //多长时间后，原料可以准备好
            dwJob["JP11"] = 0;//没有原料信息，默认已经准备好
            if (TBMAT == null)
                return;
            DateTime JobReady = new DateTime();
            filter = "JWS='J' AND ABAID='" + dwJob["ABAID"].ToString()+"'";
            sort = "ENDATE DESC,ENDTIME DESC";
            rows = TBMAT.Select(filter, sort);
            foreach (DataRow row in rows)
            {
                //MATREADYDATE
                //MATREADYTIME

                dwJob["MATREADYDATE"] = row["ENDATE"].ToString();
                dwJob["MATREADYTIME"] = row["ENDTIME"].ToString();
                string jreadydate = dwJob["JP09"].ToString();
                string jreadytime = dwJob["JP10"].ToString();
                if (jreadydate == "0")
                    jreadydate = "20010101";
                Helper.GetDateTime(ref JobReady, jreadydate, jreadytime);
                double span = JobReady.Subtract(HLATIME).TotalMinutes;
                if (span < 0)
                    span = 0;

                dwJob["JP11"] = Helper.RoundX(span, 1);
                break;
            }

        }

        public virtual void ReSetMachine()
        {
            string sdate = "", syear = "", smonth = "", sday = "";
            Helper.GetDate(ref sdate, ref syear, ref smonth, ref sday);
            DateTime now = DateTime.Now;
            string stime = Helper.Right("00" + now.Hour, 2) + Helper.Right("00" + now.Minute, 2);
            foreach (DataRow dwMachine in TBAM.Rows)
            {
                dwMachine["AMAENDZL"] = 1;//排产最后日期
                dwMachine["AMAENDDAT"] = 0;//排产最后日期
                dwMachine["AMNEUDAT"] = "0000";//排产最后时间
                string MachineID = dwMachine["MACHINEID"].ToString();
                UIAM m = ((UIAM)MachinesLib[MachineID]);
                m.dwMachine = dwMachine;
                m.ReSet(SetData, sdate, stime);
            }
        }
        /// <summary>
        /// 排产规则：20141030
        /// 1.建立任务列表，每次取出一个任务ID
        /// 2.如果排产成功，更新整个环境
        /// 3. 寻找到合适的机型，获取Job-machine最优值
        /// 4. 安排到机台，Job-Job rules，队列中的任务优化顺序
        /// 5. 平衡安排到机台
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <param name="p3"></param>
        /// <param name="p4"></param>
        /// <param name="p5"></param>
        /// <returns></returns>

        public string ABAID = "0";


        /// <summary>
        /// 1.找到最早完成的机台
        /// 2.计算加工时间
        /// 3.确定开始时间和结束时间
        /// 4.更新设备结束时间
        /// </summary>
        /// <param name="SetDetail"></param>
        /// <param name="SetData"></param>
        /// <param name="SetEnv"></param>
        /// <param name="dwInput"></param>
        /// 根据当前设备的运行，在指定时间窗内找到最合适的一个任务。
        /// 机台号1，接下来有10个任务，从切换时间最短角度，选择最合适的任务
        public virtual void ScheduleMachineType(DataRow dwSTDM)
        {
            if (dwSTDM == null)
                return;
            string STDM = dwSTDM["MACHINEID"].ToString();


            //相同颜色在相同染缸上进行
            //否则按照染缸完成时间进行排序 
            int queuelg = 10;
            int idx = 0;

            UIAM Machine = null;
            double processtime = 0;
            DateTime PlanEndTime = new DateTime(9999, 1, 1, 1, 1, 1);
            double LockTime = 0;
            string LockID = "";
            DateTime JobStart = new DateTime();
            DateTime JobEnd = new DateTime();
            SortedDictionary<long, string> BestJob = new SortedDictionary<long, string>();
            while (true)
            {
                var qjob = from DataRow row in SIMULATIONUSEDJOBS.AsEnumerable()
                           where row["MACHINEID"].ToString() == STDM
                           && row["JOBTYPE"].ToString() == " "
                            && row["MATBLOCKID"].ToString() == "0"
                           orderby row.Field<Decimal>("MKFPLTIME")
                           select row;
                if (qjob.Count() == 0)
                    break;//如果该机型的任务都安排好了，退出
                filter = "AMKSTKRS='" + dwSTDM["AMKSTKRS"].ToString() + "' AND AMKST='" + dwSTDM["AMKST"].ToString() + "' AND AMTYP='" + dwSTDM["AMTYP"].ToString() + "' AND SMTYP='" + dwSTDM["SMTYP"].ToString() + "'";
                sort = "AMAENDDAT ASC,AMNEUDAT ASC";//按照结束时间排序
                DataRow[] qMachine = TBAM.Select(filter, sort);
                foreach (DataRow dwMachine in qMachine)//定位到一个设备,每次安排一个设备
                {
                    BestJob = new SortedDictionary<long, string>();
                    string MachineID = dwMachine["MACHINEID"].ToString();
                    Machine = ((UIAM)MachinesLib[MachineID]);
                    if (Machine == null)
                        continue;
                    #region========找到最合适的任务===========  
                    string jobs = "";
                    int iJob = 0; 
                    foreach (DataRow dwJob in qjob)
                    {
                        jobs += dwJob["ABAID"].ToString() + ";";
                        processtime = Machine.CalculateProcessingTime(dwJob);
                        Machine.LockDateTimeBYcost(dwJob, processtime, ref JobStart, ref JobEnd, ref LockTime, ref LockID);
                        if (!BestJob.ContainsKey(JobEnd.ToFileTime()))
                        {
                            BestJob[JobEnd.ToFileTime()] = dwJob["ABAID"].ToString();
                        }
                        iJob++;
                        if (iJob > queuelg) break;
                    } 
                    if (BestJob.Count == 0)
                        continue;
                    foreach (KeyValuePair<long, string> kp in BestJob)
                    {
                        jobs += ",,,," + kp.Value + ";";
                        filter = "ABAID='" + kp.Value + "'";
                        rows = SIMULATIONUSEDJOBS.Select(filter);
                        foreach (DataRow dwJob in rows)
                        {
                            Machine.PushJob(dwJob); 
                            RefreshJobDB(dwJob);
                        }
                        break;
                    }

                    #endregion
                    break;//每次安排一个设备
                }
            }
        }
        Object thisLock = new Object();
        public void RefreshJobDB(DataRow dwJob)
        {
            lock (thisLock)
            {
                #region==同步更新数据========
            dwJob["JOBTYPE"] = "S";
            filter = "ABAID='" + dwJob["ABAID"].ToString()+"'";
            rows = SIMULATIONUSEDJOBS.Select(filter);
            foreach (DataRow rd in rows)
            {
                rd["ABFBNRKRS"] = dwJob["ABFBNRKRS"];
                rd["ABFBLFDNR"] = dwJob["ABFBLFDNR"];
                rd["ABFBPOS"] = dwJob["ABFBPOS"];
                rd["MACHINEID"] = dwJob["MACHINEID"];
                rd["MKFPLDATV"] = dwJob["MKFPLDATV"];
                rd["MKFPLTIME"] = dwJob["MKFPLTIME"];
                rd["MKFSCHICHTV"] = dwJob["MKFSCHICHTV"];
                rd["ABFAMASCHZT"] = dwJob["ABFAMASCHZT"];
                rd["MKFLFDNR"] = dwJob["MKFLFDNR"];
                
                rd["ENDATE"] = dwJob["ENDATE"];
                rd["ENDTIME"] = dwJob["ENDTIME"];
                rd["JOBTYPE"] = dwJob["JOBTYPE"];

            }
            filter = "MATBLOCKID LIKE '" + dwJob["ABAID"].ToString() + ";%'";
            rows = SIMULATIONUSEDJOBS.Select(filter);
            foreach (DataRow rd in rows)
            {
                rd["MATBLOCKID"] = 0;
                rd["MATREADYDATE"] = dwJob["ENDATE"];
                rd["MATREADYTIME"] = dwJob["ENDTIME"];
            }

            if (BASICJOBS != null)
            {
                filter = "ABAID='" + dwJob["ABAID"].ToString() + "'";
                DataRow[] rows1 = BASICJOBS.Select(filter);
                foreach (DataRow rbase in rows1)
                {
                    rbase["ABFBNRKRS"] = dwJob["ABFBNRKRS"];
                    rbase["ABFBLFDNR"] = dwJob["ABFBLFDNR"];
                    rbase["ABFBPOS"] = dwJob["ABFBPOS"];
                    rbase["MKFPLDATV"] = dwJob["MKFPLDATV"];
                    rbase["MKFPLTIME"] = dwJob["MKFPLTIME"];
                    rbase["MKFSCHICHTV"] = dwJob["MKFSCHICHTV"];
                    rbase["MKFLFDNR"] = dwJob["MKFLFDNR"];
                    rbase["MACHINEID"] = dwJob["MACHINEID"];
                    rbase["ABFAMASCHZT"] = dwJob["ABFAMASCHZT"];
                    rbase["ENDATE"] = dwJob["ENDATE"];
                    rbase["ENDTIME"] = dwJob["ENDTIME"];
                    rbase["JOBTYPE"] = dwJob["JOBTYPE"];
                }
                filter = "MATBLOCKID LIKE '" + dwJob["ABAID"].ToString() + ";%'";
                rows = BASICJOBS.Select(filter);
                foreach (DataRow rd in rows)
                {
                    rd["MATREADYDATE"] = dwJob["ENDATE"];
                    rd["MATREADYTIME"] = dwJob["ENDTIME"];
                }
            }
                #endregion
            }
        }


        #region=======RULES===========

        public void EvaluateMachine(DataRow job)
        {

            var qM = from DataRow dwMachine in TBSTDM.AsEnumerable()
                     where dwMachine["AMKSTKRS"].ToString().Trim() == job["ABFKSTKRS"].ToString().Trim()
                     && dwMachine["AMKST"].ToString().Trim() == job["ABFKST"].ToString().Trim()
                     && dwMachine["AMTYP"].ToString().Trim() == job["ABFMTYP"].ToString().Trim()
                     select dwMachine;
            foreach (DataRow dwMachine in TBSTDM.Rows)
            {
                dwMachine["JMVALUE"] = 0;
                if (dwMachine["MTYPE"].ToString() != job["ABFKSTKRS"].ToString() + job["ABFKST"].ToString() + job["ABFMTYP"].ToString())
                {
                    continue;
                }
                JMRULES.RValidate(dwMachine, job);
            }
        }
        #endregion
        #region========UpdateAB========
        //这里应当是处理配套规则，也就是同一生产单的不同批次，优先级提高
        public virtual void UpdateAB(DataRow dwInput)
        {
            filter = "ABAID='" + dwInput["ABAID"].ToString()+"'";
            rows = TVKPJOBS.Select(filter);

            foreach (DataRow row in rows)
            {
                row["JOBTYPE"] = dwInput["JOBTYPE"];
                row["ABFBNRKRS"] = dwInput["ABFBNRKRS"];
                row["ABFBLFDNR"] = dwInput["ABFBLFDNR"];
                row["ABFBPOS"] = dwInput["ABFBPOS"];
                row["MKFPLTIME"] = dwInput["MKFPLTIME"];
                row["TPAUTO"] = dwInput["TPAUTO"];
                row["BLOCKEDID"] = dwInput["BLOCKEDID"]; 
                row["MATBLOCKID"] = dwInput["MATBLOCKID"];
            }

            filter = "ABAID='" + dwInput["ABAID"].ToString() + "'";
            rows = BASICJOBS.Select(filter);
            foreach (DataRow row in rows)
            {
                row["JOBTYPE"] = dwInput["JOBTYPE"];
                row["ABFBNRKRS"] = dwInput["ABFBNRKRS"];
                row["ABFBLFDNR"] = dwInput["ABFBLFDNR"];
                row["ABFBPOS"] = dwInput["ABFBPOS"];
                row["MKFPLTIME"] = dwInput["MKFPLTIME"];
                row["TPAUTO"] = dwInput["TPAUTO"];
                row["BLOCKEDID"] = dwInput["BLOCKEDID"];
                
                row["MATBLOCKID"] = dwInput["MATBLOCKID"];
            } 
            string blocked = dwInput["ABAID"].ToString();
            filter = "BLOCKEDID LIKE '" + blocked + ";%'";
            rows = TVKPJOBS.Select(filter);
            foreach (DataRow row in rows)
            {
                row["BLOCKEDID"] = row["BLOCKEDID"].ToString().Replace(blocked + ";", "0");
            }
        }

        public virtual void UpdateArticle(DataRow dwInput)
        {
            if (dwInput == null)
                return;
            try
            {
                filter = "VAFPART='" + dwInput["VAFPART"].ToString() + "' AND VAFPVAR='" + dwInput["VAFPVAR"].ToString() + "' AND VAFFFARBE='" + dwInput["VAFFFARBE"].ToString() + "'";
                rows = TVKPJOBS.Select(filter);
                foreach (DataRow row in rows)
                {
                    //VKKLINES	SVKKLINES	RVKKLINES	JNUM	WNUM	JWNUM	JDNUM	WDNUM	JWDNUM	JDRATIO	WDRATIO	JWDRATIO

                    double VKKLINES = Convert.ToDouble(row["VKKLINES"].ToString());
                    double SVKKLINES = Convert.ToDouble(row["SVKKLINES"].ToString());
                    double RVKKLINES = Convert.ToDouble(row["RVKKLINES"].ToString());
                    double JNUM = Convert.ToDouble(row["JNUM"].ToString());
                    double WNUM = Convert.ToDouble(row["WNUM"].ToString());
                    double JWNUM = Convert.ToDouble(row["JWNUM"].ToString());
                    double JDNUM = Convert.ToDouble(row["JDNUM"].ToString());
                    double WDNUM = Convert.ToDouble(row["WDNUM"].ToString());
                    double JWDNUM = Convert.ToDouble(row["JWDNUM"].ToString());
                    double JDRATIO = Convert.ToDouble(row["JDRATIO"].ToString());
                    double WDRATIO = Convert.ToDouble(row["WDRATIO"].ToString());
                    double JWDRATIO = Convert.ToDouble(row["JWDRATIO"].ToString());
                    if (dwInput["JWS"].ToString().ToString() == "J")
                    {
                        if (JDNUM < JNUM)
                        {
                            JDNUM++;
                            row["JDNUM"] = JDNUM;
                            row["JDRATIO"] = Math.Round(JDNUM / JNUM, 3) * 1000;
                        }
                    }
                    else
                    {
                        if (WDNUM < WNUM)
                        {
                            WDNUM++;
                            row["WDNUM"] = WDNUM;
                            row["WDRATIO"] = Math.Round(WDNUM / WNUM, 3) * 1000;
                        }
                    }
                    JWDNUM = JDNUM + WDNUM;
                    if (JWNUM == 0)
                    {
                        JWNUM = 1;
                        WDNUM = 1;
                    }
                    JWDRATIO = Math.Round(WDNUM / JWNUM, 3) * 1000;
                    row["JWDNUM"] = JWDNUM;
                    row["JWDRATIO"] = JWDRATIO;
                }
            }
            catch (Exception ex)
            {
                LogHelper.error(ex.StackTrace + ex.Message);
            }
        }

        public virtual void UpdateMAT(DataRow dwInput)
        {
            if (dwInput == null)
                return;
            try
            {
                filter = "VAFPART='" + dwInput["VAFPART"].ToString() + "' AND VAFPVAR='" + dwInput["VAFPVAR"].ToString() + "' AND VAFFFARBE='" + dwInput["VAFFFARBE"].ToString() + "'";
                rows = TVKPJOBS.Select(filter);
                foreach (DataRow row in rows)
                {
                    //VKKLINES	SVKKLINES	RVKKLINES	JNUM	WNUM	JWNUM	JDNUM	WDNUM	JWDNUM	JDRATIO	WDRATIO	JWDRATIO

                    double VKKLINES = Convert.ToDouble(row["VKKLINES"].ToString());
                    double SVKKLINES = Convert.ToDouble(row["SVKKLINES"].ToString());
                    double RVKKLINES = Convert.ToDouble(row["RVKKLINES"].ToString());
                    double JNUM = Convert.ToDouble(row["JNUM"].ToString());
                    double WNUM = Convert.ToDouble(row["WNUM"].ToString());
                    double JWNUM = Convert.ToDouble(row["JWNUM"].ToString());
                    double JDNUM = Convert.ToDouble(row["JDNUM"].ToString());
                    double WDNUM = Convert.ToDouble(row["WDNUM"].ToString());
                    double JWDNUM = Convert.ToDouble(row["JWDNUM"].ToString());
                    double JDRATIO = Convert.ToDouble(row["JDRATIO"].ToString());
                    double WDRATIO = Convert.ToDouble(row["WDRATIO"].ToString());
                    double JWDRATIO = Convert.ToDouble(row["JWDRATIO"].ToString());
                    if (dwInput["JWS"].ToString().ToString() == "J")
                    {
                        if (JDNUM < JNUM)
                        {
                            JDNUM++;
                            row["JDNUM"] = JDNUM;
                            row["JDRATIO"] = Math.Round(JDNUM / JNUM, 3) * 1000;
                        }
                    }
                    else
                    {
                        if (WDNUM < WNUM)
                        {
                            WDNUM++;
                            row["WDNUM"] = WDNUM;
                            row["WDRATIO"] = Math.Round(WDNUM / WNUM, 3) * 1000;
                        }
                    }
                    JWDNUM = JDNUM + WDNUM;
                    if (JWNUM == 0)
                    {
                        JWNUM = 1;
                        WDNUM = 1;
                    }
                    JWDRATIO = Math.Round(WDNUM / JWNUM, 3) * 1000;
                    row["JWDNUM"] = JWDNUM;
                    row["JWDRATIO"] = JWDRATIO;
                }
            }
            catch (Exception ex)
            {
                LogHelper.error(ex.StackTrace + ex.Message);
            }
        }

        public virtual void UpdateVKK(DataRow dwInput)
        {
            if (dwInput == null)
                return;
            try
            {
                double VKKLINES = 0;
                double SVKKLINES = 0;
                filter = "VKPAUFKRS='" + dwInput["VKPAUFKRS"].ToString() + "' AND VKPAUFLFD='" + dwInput["VKPAUFLFD"].ToString() + "'";
                rows = TVKPJOBS.Select(filter);

                foreach (DataRow row in rows)
                {
                    //VKKLINES	SVKKLINES	RVKKLINES	JNUM	WNUM	JWNUM	JDNUM	WDNUM	JWDNUM	JDRATIO	WDRATIO	JWDRATIO
                    VKKLINES = Convert.ToDouble(row["VKKLINES"].ToString());
                    double JWDNUM = Convert.ToDouble(row["JWDNUM"].ToString());
                    if (JWDNUM > 0)
                    {
                        SVKKLINES++;
                    }
                }
                foreach (DataRow row in rows)
                {
                    row["SVKKLINES"] = SVKKLINES;
                    if (VKKLINES == 0)
                    {
                        row["RVKKLINES"] = 1000;
                    }
                    else
                    {
                        if (SVKKLINES > VKKLINES)
                        {
                            SVKKLINES = VKKLINES;
                        }
                        row["RVKKLINES"] = Math.Round(SVKKLINES / VKKLINES, 3) * 1000;
                    }
                }
            }
            catch (Exception ex)
            {
                LogHelper.error(ex.StackTrace + ex.Message);
            }
        }
        #endregion


        public void PlanMachineType(DataRow dwInput)
        {
            if (dwInput == null)
                return;
            string enddate = "", endtime = "";
            string MACHINEID = dwInput["MACHINEID"].ToString();

            var qjob = from DataRow row in SIMULATIONUSEDJOBS.AsEnumerable()
                       where row["MACHINEID"].ToString() == MACHINEID
                       orderby row.Field<Decimal>("MKFPLTIME")
                       select row;
            //相同颜色在相同染缸上进行
            //否则按照染缸完成时间进行排序
            int count = qjob.Count();
            int idx = 0;
            if (count == 0)
                return;
            while (true)
            {
                if (idx >= count)
                    break;
                foreach (DataRow dwJob in qjob)
                {
                    #region===选择最优化的机台==========
                    idx++;
                    string filter = "AMKSTKRS='" + dwInput["AMKSTKRS"].ToString() + "' AND AMKST='" + dwInput["AMKST"].ToString() + "' AND AMTYP='" + dwInput["AMTYP"].ToString() + "' AND SMTYP='" + dwInput["SMTYP"].ToString() + "'";
                    string sort = "AMAENDDAT ASC,AMNEUDAT ASC";
                    DataRow[] qMachine = TBAM.Select(filter, sort);
                    string BestMachineID = null;
                    double processtime = 0;
                    DateTime PlanEndTime = new DateTime(9999, 1, 1, 1, 1, 1);
                    UIAM Machine = null;
                    foreach (DataRow dwMachine in qMachine)
                    {
                        string MachineID = dwMachine["MACHINEID"].ToString();
                        #region====获取开始时间，计算占用时间=========
                        Machine = (UIAM)MachinesLib[MachineID];
                        if (Machine == null)
                            continue;
                        processtime = 480;
                        //row["AMAENDDAT"] = 0;//排产最后日期
                        double LockTime = 0;
                        string LockID = "";
                        DateTime JobStart = new DateTime();
                        DateTime JobEnd = new DateTime();
                        Machine.GetLockDateTime(dwJob, processtime, ref JobStart, ref JobEnd, ref LockTime, ref LockID);
                        dwJob["SFILETME"] = JobStart.ToFileTime();
                        dwJob["EFILETME"] = JobEnd.ToFileTime();
                        if (JobEnd < PlanEndTime)
                        {
                            PlanEndTime = JobEnd;
                            BestMachineID = MachineID;
                        }
                        if (LockTime == 0)
                            break;
                        #endregion
                        //break;//找到设备就退出
                    }
                    #endregion
                    #region===找到最佳设备=======
                    filter = "MACHINEID='" + BestMachineID + "'";
                    var query = from DataRow dwBest in TBAM.AsEnumerable()
                                where dwBest["MACHINEID"].ToString() == BestMachineID
                                select dwBest;
                    foreach (DataRow dwBest in query)
                    {
                        Machine = (UIAM)MachinesLib[BestMachineID];
                        Machine.PlanJob(dwJob);
                    }
                    #endregion
                    #region==同步更新数据========

                    var qD = from DataRow rd in TVKPJOBS.AsEnumerable()
                             where rd["ABAID"].ToString() == dwJob["ABAID"].ToString()
                             select rd;
                    foreach (DataRow rd in qD)
                    {
                        rd["ABFBNRKRS"] = dwJob["ABFBNRKRS"];
                        rd["ABFBLFDNR"] = dwJob["ABFBLFDNR"];
                        rd["ABFBPOS"] = dwJob["ABFBPOS"];
                        rd["MKFLFDNR"] = dwJob["MKFLFDNR"];
                        rd["MACHINEID"] = dwJob["MACHINEID"];
                        rd["JOBTYPE"] = dwJob["JOBTYPE"];
                        rd["SFILETME"] = dwJob["SFILETME"] ;
                        rd["EFILETME"] = dwJob["EFILETME"];
                        if (BASICJOBS != null)
                        {
                            var qB = from DataRow rbase in BASICJOBS.AsEnumerable()
                                     where rbase["ABAID"].ToString() == rd["ABAID"].ToString()
                                     select rbase;
                            foreach (DataRow rbase in qB)
                            {
                                rbase["ABFBNRKRS"] = dwJob["ABFBNRKRS"];
                                rbase["ABFBLFDNR"] = dwJob["ABFBLFDNR"];
                                rbase["ABFBPOS"] = dwJob["ABFBPOS"];
                                rbase["MKFLFDNR"] = dwJob["MKFLFDNR"];
                                rbase["MACHINEID"] = dwJob["MACHINEID"];
                                rbase["ABFAMASCHZT"] = dwJob["ABFAMASCHZT"];
                                rbase["JOBTYPE"] = dwJob["JOBTYPE"];
                                rbase["SFILETME"] = dwJob["SFILETME"];
                                rbase["EFILETME"] = dwJob["EFILETME"];
                            }
                        }
                    }
                    #endregion
                }
            }
            #region===设备负载平衡优化========
            #endregion
        }
        public DataSet StartPlan(object p1 = null, object p2 = null, object p3 = null, object p4 = null, object p5 = null)
        {
            SetProd = (DataSet)p1;
            SetEnv = (DataSet)p2;
            SetData = (DataSet)p3;
            string sdate = "", syear = "", smonth = "", sday = "";
            Helper.GetDate(ref sdate, ref syear, ref smonth, ref sday);
            DateTime now = DateTime.Now;
            string stime = Helper.Right("00" + now.Hour, 2) + Helper.Right("00" + now.Minute, 2);
            DataRow srow = null;
            DataRow nSchedule = null;
            string filter = "";
            string sort = "";
            #region===初始化可排产任务=========
            SIMULATIONUSEDJOBS.Clear();
            string processed = "";

            //这里处理了已经确认或已经生成的任务，不允许移动位置
            //对于日历，也要进行相同的处理。
            //需要注意排序的规则和时间
            var qjob = from DataRow row in TVKPJOBS.AsEnumerable()
                       orderby row.Field<string>("ABFSTATUS") descending
                       orderby row.Field<string>("SPCONFIRM") descending
                       select row;
            foreach (DataRow row in qjob)
            {
                if (row["ABFSTATUS"].ToString() == "R")
                {
                    continue;
                }
                if (row["JOBTYPE"].ToString().Trim() == "C")
                {
                    continue;
                }
                if (row["JOBTYPE"].ToString().Trim() == "X")//日历任务
                {
                    continue;
                }
                row["ABFBLFDNR"] = "0000";
            }
            #endregion
            #region=====初始化设备=======
            foreach (DataRow dwMachine in TBAM.Rows)
            {
                dwMachine["AMAENDZL"] = 1;//排产最后日期
                dwMachine["AMAENDDAT"] = 0;//排产最后日期
                dwMachine["AMNEUDAT"] = "0000";//排产最后时间
                string MachineID = dwMachine["MACHINEID"].ToString();
                UIAM m = (UIAM)MachinesLib[MachineID];
                m.dwMachine = dwMachine;
                m.ReSet(SetData, sdate, stime);
            }
            #endregion
            int totalcount = this.TBSTDM.Rows.Count * TVKPJOBS.Rows.Count;
            int Runs = 0;
            #region======确定机型===========
            while (true)
            {
                if (Runs > totalcount)
                    break;
                Runs++;
                nSchedule = null;
                filter = "ABFKST='9999'";
                sort = "JP06 DESC,ABFAUFKRS ASC,ABFAUFLFD ASC,ABFAUFPOS ASC";
                rows = TVKPJOBS.Select(filter, sort);
                foreach (DataRow dwJob in rows)
                {
                    string ABAID = dwJob["ABAID"].ToString() + ";";
                    if (processed.Contains(ABAID))
                    {
                        continue;
                    }
                    processed += ABAID;
                    DataRow dwMachine = null;
                    string ABPTYPE = dwJob["ABPTYPE"].ToString().Trim();
                    string POSTYP = dwJob["POSTYP"].ToString().Trim();
                    string ABTYPE = (ABPTYPE + POSTYP).Trim();
                    string SMTYP = "";
                    switch (ABTYPE)
                    {
                        case "GPXS":
                        case "GPSP":
                            SMTYP = "XS";
                            break;
                        case "GPHM":
                            SMTYP = "QF";
                            break;
                        case "GPBX":
                            SMTYP = "BX";
                            break;
                        case "GBJobBar":
                            SMTYP = "FP";
                            break;
                        case "GPMU":
                        case "GPDE":
                        case "GPJH":
                        case "GPLS":
                            SMTYP = "FP";
                            break;
                        case "GPRS":
                            SMTYP = "YD";
                            break;
                        case "VFFI":
                        case "VAFI":
                        case "MUFI":
                            SMTYP = "FF";
                            break;
                        case "VW":
                            SMTYP = "PP";
                            break;
                        case "PR":
                            SMTYP = "WV";
                            break;
                        case "DI":
                            SMTYP = "WV";
                            break;
                        default:
                            SMTYP = "FP";
                            break;
                    }
                    if (ABPTYPE == "VK")
                    {
                        SMTYP = "VK";
                    }
                    var qM = from DataRow stdm in TBSTDM.AsEnumerable()
                             where stdm["SMTYP"].ToString().Trim() == SMTYP
                             select stdm;
                    foreach (DataRow stdm in qM)
                    {
                        dwMachine = stdm;
                        break;
                    }
                    if (dwMachine == null)
                        continue;
                    dwJob["MACHINEID"] = dwMachine["MACHINEID"];
                    dwJob["MKFPLTIME"] = Runs;
                    srow = SIMULATIONUSEDJOBS.NewRow();
                    srow.ItemArray = dwJob.ItemArray;
                    SIMULATIONUSEDJOBS.Rows.Add(srow);
                    nSchedule = srow;
                    break;
                }
            }
            #endregion
            #region====分配机台=======
            foreach (DataRow dwMachine in TBSTDM.Rows)
            {
                PlanMachineType(dwMachine);
            }
            #endregion
            return SetData;
        }

    }
}

